(defpackage :lem-scheme-syntax.data
  (:use :cl :lem)
  (:export :get-scheme-completion-data
           :get-scheme-highlight-data
           :get-scheme-indentation-data))
(in-package :lem-scheme-syntax.data)

(defvar *scheme-data*
  ;; name  completion  highlight  indentation
  '(;; == part 0 ==
    ("use"                            t   t   0)
    ("import"                         t   t   0)
    ("select-module"                  t   t   0)
    ("cond"                           t   t   (&rest (&whole 1 &rest 1)))
    ("cond-expand"                    t   t   "cond")
    ("list"                           t   t   nil)
    ("vector"                         t   t   nil)
    ("set!"                           t   t   nil)
    ("eq?"                            t   t   nil)
    ("eqv?"                           t   t   nil)
    ("equal?"                         t   t   nil)
    ("and"                            t   t   nil)
    ("or"                             t   t   nil)
    ("not"                            t   t   nil)
    ("print"                          t   t   nil)
    ("display"                        t   t   nil)
    ("format"                         t   t   nil)
    ("newline"                        t   t   nil)
    ("flush"                          t   t   nil)
    ("read"                           t   t   nil)
    ("read-line"                      t   t   nil)
    ("write"                          t   t   nil)
    ("apply"                          t   t   nil)
    ("eval"                           t   t   nil)
    ("exit"                           t   t   nil)
    ("call-with-current-continuation" t   t   nil)
    ("call/cc"                        t   t   nil)
    ("raise"                          t   t   nil)
    ("map"                            t   t   nil)
    ("for-each"                       t   t   nil)
    ("case-lambda"                    t   t   (&rest (&whole 2 &rest 1)))
    ("er-macro-transformer"           t   t   nil)

    ;; == part 1 ==
    ("begin"                          t   t   0)
    ("case"                           t   t   (4 &rest (&whole 2 &rest 1)))
    ("def"                            t   t   1)
    ("define"                         t   t   1)
    ("define-library"                 t   t   1)
    ("define-record-type"             t   t   3)
    ("define-syntax"                  t   t   1)
    ("define-values"                  t   t   1)
    ("delay"                          t   t   0)
    ("do"                             t   t   2)
    ("export"                         t   t   0)
    ("if"                             t   t   1)
    ("lambda"                         t   t   1)
    ("let"                            t   t   ((&whole 4 &rest (&whole 1 2)) &body))
    ("let*"                           t   t   "let")
    ("letrec"                         t   t   "let")
    ("letrec*"                        t   t   "let")
    ("library"                        t   t   1)
    ("syntax-case"                    t   t   2)
    ("with-input-from-file"           t   t   1)
    ("with-output-to-file"            t   t   1)

    ;; == part 2 ==
    ("define-class"                   t   t   2)
    ("define-condition-type"          t   t   3)
    ("define-constant"                t   t   1)
    ("define-dict-interface"          t   t   1)
    ("define-in-module"               t   t   2)
    ("define-macro"                   t   t   1)
    ("define-method"                  t   t   2)
    ("define-module"                  t   t   1)
    ("define-reader-ctor"             t   t   1)
    ("and-let1"                       t   t   2)
    ("ecase"                          t   t   "case")
    ("glet1"                          t   t   2)
    ("hash-table"                     t   t   "define")
    ("if-let1"                        t   t   2)
    ("match-lambda"                   t   t   "cond")
    ("match-lambda*"                  t   t   "cond")
    ("match-let"                      t   t   "let")
    ("match-let*"                     t   t   "let")
    ("match-letrec"                   t   t   "let")
    ("match-let1"                     t   t   2)
    ("quasirename"                    t   t   1)
    ("rlet1"                          t   t   2)
    ("unwind-protect"                 t   t   1)
    ("with-ports"                     t   t   3)

    ;; == part 3 ==
    ("and-let*"                       t   t   "let")
    ("begin0"                         t   t   0)
    ("call-with-client-socket"        t   t   1)
    ("call-with-input-conversion"     t   t   1)
    ("call-with-input-file"           t   t   1)
    ("call-with-input-process"        t   t   1)
    ("call-with-input-string"         t   t   1)
    ("call-with-iterator"             t   t   1)
    ("call-with-output-conversion"    t   t   1)
    ("call-with-output-file"          t   t   1)
    ("call-with-output-string"        t   t   0)
    ("call-with-temporary-file"       t   t   1)
    ("call-with-values"               t   t   1)
    ("dolist"                         t   t   1)
    ("dotimes"                        t   t   1)
    ("if-match"                       t   t   2)
    ("let*-values"                    t   t   "let")
    ("let-args"                       t   t   (4 (&whole 4 &rest (&whole 1 2)) &body))
    ("let-keywords*"                  t   t   "let-args")
    ("let-match"                      t   t   "let-args")
    ("let-optionals*"                 t   t   "let-args")
    ("let-syntax"                     t   t   "let")
    ("let-values"                     t   t   "let")
    ("let/cc"                         t   t   1)
    ("let1"                           t   t   2)
    ("letrec-syntax"                  t   t   "let")
    ("make"                           t   t   1)
    ("multiple-value-bind"            t   t   2)
    ("match"                          t   t   "case")
    ("parameterize"                   t   t   1)
    ("parse-options"                  t   t   "case")
    ("receive"                        t   t   2)
    ("rxmatch-case"                   t   t   "case")
    ("rxmatch-cond"                   t   t   "cond")
    ("rxmatch-if"                     t   t   2)
    ("rxmatch-let"                    t   t   "let-args")
    ("syntax-rules"                   t   t   1)
    ("unless"                         t   t   1)
    ("until"                          t   t   1)
    ("when"                           t   t   1)
    ("while"                          t   t   1)
    ("with-builder"                   t   t   1)
    ("with-error-handler"             t   t   0)
    ("with-error-to-port"             t   t   1)
    ("with-input-conversion"          t   t   1)
    ("with-input-from-port"           t   t   1)
    ("with-input-from-process"        t   t   1)
    ("with-input-from-string"         t   t   1)
    ("with-iterator"                  t   t   1)
    ("with-module"                    t   t   1)
    ("with-output-conversion"         t   t   1)
    ("with-output-to-port"            t   t   1)
    ("with-output-to-process"         t   t   1)
    ("with-output-to-string"          t   t   0)
    ("with-port-locking"              t   t   1)
    ("with-string-io"                 t   t   1)
    ("with-time-counter"              t   t   1)
    ("with-signal-handlers"           t   t   1)
    ("with-locking-mutex"             t   t   1)
    ("guard"                          t   t   1)))

(defun get-scheme-completion-data ()
  (sort (mapcar #'first (remove-if-not #'second *scheme-data*))
        #'string<))

(defun get-scheme-highlight-data ()
  (mapcar #'first (remove-if-not #'third *scheme-data*)))

(defun get-scheme-indentation-data ()
  (mapcar (lambda (d)
            (let ((name   (first  d))
                  (indent (fourth d)))
              (if (stringp indent)
                  (cons name indent)
                  (list name indent))))
          (remove-if-not #'fourth *scheme-data*)))
